home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Complete Linux
/
Complete Linux.iso
/
xwindows
/
demos
/
xfract_1.z
/
xfract_1
/
xfractint-1.06
/
parser.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-28
|
53KB
|
2,172 lines
/* Parser.c (C) 1990, Mark C. Peterson, CompuServe [70441,3353]
All rights reserved.
Code may be used in any program provided the author is credited
either during program execution or in the documentation. Source
code may be distributed only in combination with public domain or
shareware source code. Source code may be modified provided the
copyright notice and this message is left unchanged and all
modifications are clearly documented.
I would appreciate a copy of any work which incorporates this code,
however this is optional.
Mark C. Peterson
405-C Queen St. Suite #181
Southington, CT 06489
(203) 276-9721
*/
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h> /* TIW 04-22-91 */
#include <time.h>
#include "mpmath.h"
#include "prototyp.h"
extern int Transparent3D; /* MCP 5-30-91 */
#ifdef WATCH_MP
double x1, y1, x2, y2;
#endif
MATH_TYPE MathType = D_MATH;
/* moved struct lcomplex and union ARg to mpmath.h -6-20-90 TIW */
/* PB 910417 added MAX_OPS and MAX_ARGS defines */
#define MAX_ARGS 100
struct ConstArg {
char *s;
int len;
union Arg a;
};
#define MAX_OPS 250
struct PEND_OP {
void (far *f)(void);
int p;
};
/* PB 901103 made some of the following static for safety */
static struct PEND_OP far *o;
static void parser_allocate(void);
union Arg *Arg1, *Arg2;
/* PB 910417 removed unused "a" array */
static union Arg s[20], far * far *Store, far * far *Load;
static int StoPtr, LodPtr, OpPtr;
static void (far * far *f)(void) = (void(far * far *)(void))0;
static unsigned n, ErrPtr, posp, vsp, NextOp, LastOp, InitN;
static int paren, SyntaxErr, ExpectingArg;
static struct ConstArg far *v = (struct ConstArg far *)0;
static int InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp;
static int Delta16;
double fgLimit; /* TIW 05-04-91 */
static double fg;
static int ShiftBack; /* TIW 06-18-90 */
static int SetRandom; /* MCP 11-21-91 */
static int Randomized;
static unsigned long RandNum;
extern int bitshift;
extern int bitshiftless1;
extern int symmetry; /* symmetry flag for calcmand() */
extern double param[];
extern int debugflag; /* BDT for debugging */
extern char boxx[8192]; /* PB 4-9-91, good place for the formula string */
extern int row, col, overflow, cpu, fpu;
extern struct complex old, new;
extern double far *dx0, far *dy0;
extern long far *lx0, far *ly0; /* BDT moved these to FAR */
#ifndef TESTING_MATH
extern double far *dx1, far *dy1;
extern long far *lx1, far *ly1;
#define dShiftx dx1[row]
#define dShifty dy1[col]
#define lShiftx lx1[row]
#define lShifty ly1[col]
#else
#define dShiftx 0.0
#define dShifty 0.0
#define lShiftx 0L
#define lShifty 0L
#endif
extern struct lcomplex lold, lnew;
extern char FormName[];
extern VOIDFARPTR typespecific_workarea;
#define LastSqr v[4].a
static char far * far ErrStrings[] = { /* TIW 03-31-91 added far */
"Should be an Argument",
"Should be an Operator",
"')' needs a matching '('",
"Need more ')'",
"Undefined Operator",
"Undefined Function",
"More than one ','",
"Table overflow"
};
unsigned SkipWhiteSpace(char *Str) {
unsigned n, Done;
for(Done = n = 0; !Done; n++) {
switch(Str[n]) {
case ' ':
case '\t':
case '\n':
case '\r':
break;
default:
Done = 1;
}
}
return(n - 1);
}
/* Random number code, MCP 11-21-91 */
unsigned long NewRandNum(void)
{
return(RandNum = ((RandNum << 15) + rand15()) ^ RandNum);
}
void lRandom(void)
{
v[7].a.l.x = NewRandNum() >> (32 - bitshift);
v[7].a.l.y = NewRandNum() >> (32 - bitshift);
}
void dRandom(void)
{
long x, y;
/* Use the same algorithm as for fixed math so that they will generate
the same fractals when the srand() function is used. */
x = NewRandNum() >> (32 - bitshift);
y = NewRandNum() >> (32 - bitshift);
v[7].a.d.x = ((double)x / (1L << bitshift));
v[7].a.d.y = ((double)y / (1L << bitshift));
}
#ifndef XFRACT
void mRandom(void)
{
long x, y;
/* Use the same algorithm as for fixed math so that they will generate
the same fractals when the srand() function is used. */
x = NewRandNum() >> (32 - bitshift);
y = NewRandNum() >> (32 - bitshift);
v[7].a.m.x = *fg2MP(x, bitshift);
v[7].a.m.y = *fg2MP(y, bitshift);
}
#endif
void SetRandFnct(void)
{
unsigned Seed;
if(!SetRandom)
RandNum = Arg1->l.x ^ Arg1->l.y;
Seed = (unsigned)RandNum ^ (unsigned)(RandNum >> 16);
srand(Seed);
SetRandom = 1;
/* Clear out the seed */
NewRandNum();
NewRandNum();
NewRandNum();
}
void RandomSeed(void)
{
time_t ltime;
/* Use the current time to randomize the random number sequence. */
time(<ime);
srand((unsigned int)ltime);
NewRandNum();
NewRandNum();
NewRandNum();
Randomized = 1;
}
#ifndef XFRACT
void lStkSRand(void)
{
SetRandFnct();
lRandom();
Arg1->l = v[7].a.l;
}
#endif
#ifndef XFRACT
void mStkSRand(void)
{
Arg1->l.x = Arg1->m.x.Mant ^ (long)Arg1->m.x.Exp;
Arg1->l.y = Arg1->m.y.Mant ^ (long)Arg1->m.y.Exp;
SetRandFnct();
mRandom();
Arg1->m = v[7].a.m;
}
#endif
void dStkSRand(void)
{
Arg1->l.x = (long)(Arg1->d.x * (1L << bitshift));
Arg1->l.y = (long)(Arg1->d.y * (1L << bitshift));
SetRandFnct();
dRandom();
Arg1->d = v[7].a.d;
}
void (*StkSRand)(void) = dStkSRand;
void dStkAbs(void) {
Arg1->d.x = fabs(Arg1->d.x);
Arg1->d.y = fabs(Arg1->d.y);
}
#ifndef XFRACT
void mStkAbs(void) {
if(Arg1->m.x.Exp < 0)
Arg1->m.x.Exp = -Arg1->m.x.Exp;
if(Arg1->m.y.Exp < 0)
Arg1->m.y.Exp = -Arg1->m.y.Exp;
}
void lStkAbs(void) {
Arg1->l.x = labs(Arg1->l.x);
Arg1->l.y = labs(Arg1->l.y);
}
#endif
void (*StkAbs)(void) = dStkAbs;
void dStkSqr(void) {
LastSqr.d.x = Arg1->d.x * Arg1->d.x;
LastSqr.d.y = Arg1->d.y * Arg1->d.y;
Arg1->d.y = Arg1->d.x * Arg1->d.y * 2.0;
Arg1->d.x = LastSqr.d.x - LastSqr.d.y;
LastSqr.d.x += LastSqr.d.y;
LastSqr.d.y = 0;
}
#ifndef XFRACT
void mStkSqr(void) {
LastSqr.m.x = *MPmul(Arg1->m.x, Arg1->m.x);
LastSqr.m.y = *MPmul(Arg1->m.y, Arg1->m.y);
Arg1->m.y = *MPmul(Arg1->m.x, Arg1->m.y);
Arg1->m.y.Exp++;
Arg1->m.x = *MPsub(LastSqr.m.x, LastSqr.m.y);
LastSqr.m.x = *MPadd(LastSqr.m.x, LastSqr.m.y);
LastSqr.m.y.Mant = (long)(LastSqr.m.y.Exp = 0);
}
void lStkSqr(void) {
LastSqr.l.x = multiply(Arg1->l.x, Arg1->l.x, bitshift);
LastSqr.l.y = multiply(Arg1->l.y, Arg1->l.y, bitshift);
Arg1->l.y = multiply(Arg1->l.x, Arg1->l.y, bitshift) << 1;
Arg1->l.x = LastSqr.l.x - LastSqr.l.y;
LastSqr.l.x += LastSqr.l.y;
LastSqr.l.y = 0L;
}
#endif
void (*StkSqr)(void) = dStkSqr;
void dStkAdd(void) {
Arg2->d.x += Arg1->d.x;
Arg2->d.y += Arg1->d.y;
Arg1--;
Arg2--;
}
#ifndef XFRACT
void mStkAdd(void) {
Arg2->m = MPCadd(Arg2->m, Arg1->m);
Arg1--;
Arg2--;
}
void lStkAdd(void) {
Arg2->l.x += Arg1->l.x;
Arg2->l.y += Arg1->l.y;
Arg1--;
Arg2--;
}
#endif
void (*StkAdd)(void) = dStkAdd;
void dStkSub(void) {
Arg2->d.x -= Arg1->d.x;
Arg2->d.y -= Arg1->d.y;
Arg1--;
Arg2--;
}
#ifndef XFRACT
void mStkSub(void) {
Arg2->m = MPCsub(Arg2->m, Arg1->m);
Arg1--;
Arg2--;
}
void lStkSub(void) {
Arg2->l.x -= Arg1->l.x;
Arg2->l.y -= Arg1->l.y;
Arg1--;
Arg2--;
}
#endif
void (*StkSub)(void) = dStkSub;
void dStkConj(void) {
Arg1->d.y = -Arg1->d.y;
}
#ifndef XFRACT
void mStkConj(void) {
Arg1->m.y.Exp ^= 0x8000;
}
void lStkConj(void) {
Arg1->l.y = -Arg1->l.y;
}
#endif
void (*StkConj)(void) = dStkConj;
void dStkReal(void) {
Arg1->d.y = 0.0;
}
#ifndef XFRACT
void mStkReal(void) {
Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0);
}
void lStkReal(void) {
Arg1->l.y = 0l;
}
#endif
void (*StkReal)(void) = dStkReal;
void dStkImag(void) {
Arg1->d.x = Arg1->d.y;
Arg1->d.y = 0.0;
}
#ifndef XFRACT
void mStkImag(void) {
Arg1->m.x = Arg1->m.y;
Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0);
}
void lStkImag(void) {
Arg1->l.x = Arg1->l